#ifndef __OPENFSM_H
#define __OPENFSM_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stdarg.h>
#include <stdint.h>

#include "openFSM_config.h"


enum condition
{
    bool_False,         /* 布尔假值条件，对应 0/false */
    bool_True,          /* 布尔真值条件，对应 1/true */
    int_Positive,       /* 整型正数条件，值 > 0 时成立 */
    int_Zero,           /* 整型零值条件，值 == 0 时成立 */
    int_Negative        /* 整型负数条件，值 < 0 时成立 */
};

struct FSM_state;

struct evnet
{
    void * UserData;
};


/**
 * @brief 状态转移条件描述结构体
 * @details 定义从当前状态切换到目标状态的条件和行为
 */
struct transition
{
    /** 
     * @brief 触发转移的事件类型标识符
     * @details 使用16位存储事件类型编码，范围0-65535
     * @note 应与事件产生模块统一编码规范
     */
    uint32_t eventType:16;

    /** 
     * @brief 转移触发条件类型
     * @details 使用condition枚举值定义判断逻辑类型
     * @see condition
     */
    uint32_t JumpCondition:16;

    /** 
     * @brief 条件满足时执行的动作函数
     * @return int 执行结果代码：
     *             - 0   继续执行转移
     *             - <0  取消转移并返回错误码
     * @note 此函数在状态转移前执行，可用于数据预处理
     */
    int ( *action )( void );

    /** 
     * @brief 目标状态指针
     * @details 当eventType和JumpCondition同时满足时，
     *          状态机将切换至此指向的状态
     */
    struct FSM_state * state;
};

// 定义FSM_state结构体
struct FSM_state
{
    /* 状态唯一标识符/名称 
     * 用于调试或显示当前状态的名称 
     */
    char *name;

    /* 状态私有数据指针 
     * 可存储状态相关的上下文数据，由用户自定义类型
     * 例如：定时器计数器、传感器历史数据等 
     */
    void *data;

    /* 状态进入动作函数指针 
     * 当状态机首次切换到此状态时触发（仅执行一次）
     * 参数 stateData: 传递给本状态私有数据的指针 
     */
    void (*entryAction)(void * stateData);

    /* 状态持续动作函数指针 
     * 在状态持续期间反复调用（例如每次状态机循环时执行）
     * 参数 stateData: 传递给本状态私有数据的指针 
     */
    void (*continuousAction)(void * stateData);

    /* 状态退出动作函数指针 
     * 当状态机离开此状态前触发（仅执行一次）
     * 参数 stateData: 传递给本状态私有数据的指针 
     */
    void (*exitAction)(void * stateData);

    /* 状态转移条件数量 
     * 使用7位无符号整数表示（最大127个转移条件）
     * 表示transitions数组的有效元素个数 
     */
    uint32_t numTransitions:7;

    /* 初始化标志位 
     * 1位标志位（0=未初始化，1=已初始化）
     * 用于防止重复运行进入动作函数
     */
    uint32_t first:1;

    /* 状态转移条件链表指针 
     * 指向transition结构体数组，定义状态转移规则
     * 每个transition包含触发条件和目标状态
     */
    struct transition * transitions;
};

struct FSM_LOG
{
    uint8_t LOG_LEVEL;
    uint8_t * LOG_Buffer;
};


typedef struct 
{
    struct FSM_LOG * LOG;
    struct FSM_state * FSM_Point;
}FSM_Info;


extern void FSM_Init(struct FSM_state ** fsmState, struct FSM_state * initialState);

extern void FSM_Run(struct FSM_state ** fsmState, void * data);

extern void FSM_PrintInfo(struct FSM_state * fsmState);


#ifdef __cplusplus
}
#endif


#endif  /* __OPENFSM_H */

